import { ThingsSyncExecutor } from '@/ts/base/model';
import { Executor } from '.';
import { FormData } from './index';
import orgCtrl from '@/ts/controller';

// 添加精确计算辅助函数
function preciseSubtract(num1: number, num2: number): number {
  const precision1 = (num1.toString().split('.')[1] || '').length;
  const precision2 = (num2.toString().split('.')[1] || '').length;
  const maxPrecision = Math.max(precision1, precision2);
  const multiplier = Math.pow(10, maxPrecision);
  
  const n1 = Math.round(num1 * multiplier);
  const n2 = Math.round(num2 * multiplier);
  return (n1 - n2) / multiplier;
}

/**
 * 台账信息同步类
 */
export class ThingsSync extends Executor<ThingsSyncExecutor> {
  /**
   * 执行台账信息同步任务
   * @param data 表单数据
   * @returns 是否成功执行
   */
  async execute(data: FormData): Promise<boolean> {
    try {
      // 获取当前实例数据
      const instance = this.task.instanceData;
      if (!instance) {
        console.error('实例数据不存在');
        return false;
      }
      if (!Array.isArray(instance.changeItems) || instance.changeItems.length === 0) {
        return true;
      }
      // 获取待处理的资产ID
      const assetIdsToProcess = new Set(
        instance.changeItems.map((asset: any) => asset.recordId ?? asset.id),
      );
      // 获取资产列表
      const assets = await this.getAssets(Array.from(assetIdsToProcess));

      // 更新资产数据
      await this.updateAssets(assets, instance.changeItems);

      // 保存更新后的资产
      await this.saveAssets(assets);

      return true;
    } catch (error) {
      console.error('同步任务执行失败:', error);
      // 可在此添加日志记录或通知逻辑
      return false;
    }
  }

  /**
   * 获取资产列表
   * @param assetIds 资产ID数组
   * @returns 资产对象数组
   */
  private async getAssets(assetIds: string[]): Promise<any[]> {
    const assets = await Promise.all(
      assetIds.map(async (assetId: string) => {
        const asset: any = this.task.instanceData?.changeItems?.find(
          (item: any) => item.recordId === assetId,
        );
        if (!asset) return null;

        const target = orgCtrl.targets.find((target) => target.id === asset.belongId);
        if (!target) return null;

        const result = await target.resource.thingColl.find([assetId]);
        return result;
      }),
    );
    return assets.filter((item) => item !== null).flat();
  }

  /**
   * 更新资产数据
   * @param assets 资产列表
   * @param changeItems 变更项列表
   */
  private async updateAssets(assets: any[], changeItems: any[]): Promise<void> {
    await Promise.all(
      changeItems.map(async (change: any) => {
        const asset = assets.find((item: any) => item.id === change.recordId);
        if (!asset) return;
        asset['locks'] = undefined;
        
        // 更新资产字段
        Object.keys(asset).forEach((key) => {
          Object.keys(change).forEach((changeKey) => {
            if (
              key.includes(changeKey) &&
              key !== changeKey &&
              asset[`T${changeKey}`] &&
              typeof asset[`T${changeKey}`] === 'number'
            ) {
              // 使用精确减法替代 Decimal
              asset[`T${changeKey}`] = preciseSubtract(
                asset[`T${changeKey}`],
                change[changeKey]
              );
            }
            if (
              key === changeKey &&
              typeof change[changeKey] === 'number' &&
              (/^(?:\d{18}|T\d+)$/.test(changeKey) || ['count'].includes(changeKey))
            ) {
              // 使用精确减法替代 Decimal
              asset[key] = preciseSubtract(asset[key], change[changeKey]);
            }
          });
        });
      }),
    );
  }

  /**
   * 保存资产到数据库
   * @param assets 资产列表
   */
  private async saveAssets(assets: any[]): Promise<void> {
    await Promise.all(
      assets.map(async (asset: any) => {
        const target = orgCtrl.targets.find((target) => target.id === asset.belongId);
        if (target) {
          await target.resource.thingColl.replace(asset);
        }
      }),
    );
  }
}
